"""
题目需求：给定一个非空字符串，最多可以删除一个字符，判断是否能成为回文串。
示例：
输入："aba"
输出：True（本身就是回文）
输入："abca"
输出：True（删除 "c" 或 "b" 后成为回文）
输入："abc"
输出：False（删除任一字符后仍不是回文）

实现思路：
判断一个非空字符串最多删除一个字符能否成为回文串，可按以下思路实现：
1:采用双指针法，初始化左指针在字符串起始位置，右指针在末尾位置。
1:左右指针同时向中间移动，比较指针所指的字符：
    若字符相等，继续移动指针。
    若字符不相等，此时有两种尝试方向：删除左指针指向的字符（左指针右移一位），或删除右指针指向的字符（右指针左移一位）。
3:对上述两种情况分别检查剩余子串是否为回文串（继续用双指针比较），只要其中一种情况能形成回文串，就返回 True。
4:若指针移动到中间位置仍未出现不相等的字符，说明原字符串本身就是回文串，返回 True；若两种删除尝试都无法形成回文串，则返回 False。

这种思路通过一次遍历配合两次分支检查，能高效判断是否满足条件，时间复杂度为 O (n)（n 为字符串长度）。

"""



"""
问题：为什么is_palindrome_range方法要写在valid_palindrome方法里面，提到外面不行吗？

答： 把 `is_palindrome_range` 写在 `valid_palindrome` 里面或者提到外面，**语法上都是可行的**，但从**代码组织、作用域、可读性**等角度来看，写在内部有其合理性，提到外面也有相应特点，具体分析如下：

### 写在内部的原因
1. **作用域限制**：`is_palindrome_range` 是专门为 `valid_palindrome` 服务的辅助函数，它只在 `valid_palindrome` 内部被调用，不需要被外部其他代码访问。将其定义在 `valid_palindrome` 内部，能限制它的作用域，避免污染全局命名空间，也让代码的逻辑封装性更好，别人看代码时能更清晰知道这个辅助函数是属于 `valid_palindrome` 这个功能的。
2. **闭包特性（可选）**：如果 `is_palindrome_range` 需要访问 `valid_palindrome` 内部的一些局部变量（虽然在这个例子中没有，但存在这种场景），定义在内部可以形成闭包，直接访问外层函数的变量，而不需要通过参数传递等更繁琐的方式。
3. **逻辑内聚性**：从代码逻辑上，`is_palindrome_range` 是 `valid_palindrome` 功能的一部分，放在内部能让相关逻辑更集中，提升代码的可读性和可维护性，一看就知道这两个函数是紧密相关的。

### 提到外面的情况
如果提到外面，也是可以的，此时需要注意：
1. **参数传递**：因为 `is_palindrome_range` 要操作字符串 `s`，所以需要把 `s` 作为参数传递给它（原来在内部可以直接访问外层函数的 `s`，提到外面后作用域不包含 `s` 了），函数定义会变成 `def is_palindrome_range(s, left, right):`，调用的时候也要传入 `s`，比如 `is_palindrome_range(s, left + 1, right)`。
2. **命名空间管理**：提到外面后，`is_palindrome_range` 成为了一个全局（或模块级）的函数，若有其他函数也可能需要类似的“检查子串是否为回文”功能，这样提取出来可以复用；但如果只有 `valid_palindrome` 用它，就会让全局命名空间多一个只被单一函数使用的辅助函数，显得冗余。

### 总结
在这个例子中，`is_palindrome_range` 是高度专属 `valid_palindrome` 的辅助函数，写在内部更能体现逻辑内聚性、限制作用域，是比较好的选择；但如果有复用需求，提到外面并调整参数传递也是可行的。具体怎么选，取决于代码的整体设计和复用需求。
"""
def valid_palindrome(s):
    # 辅助函数：检查子串s[left:right+1]是否为回文
    def is_palindrome_range(left, right):
        while left < right:
            if s[left] != s[right]:
                return False
            left += 1
            right -= 1
        return True
    # 初始化左右指针
    left = 0
    right = len(s) - 1
    while left < right:
        # 若字符不匹配，尝试删除左或右字符后检查
        if s[left] != s[right]:
            # 两种可能：删除左字符或删除右字符  注意这里用的是or
            return is_palindrome_range(left + 1, right) or is_palindrome_range(left, right - 1)
        # 字符匹配，移动指针
        left += 1
        right -= 1
    # 本身就是回文
    return True

# 测试
print(valid_palindrome("aba"))  # 输出: True
print(valid_palindrome("abca"))  # 输出: True
print(valid_palindrome("abc"))  # 输出: False

s = "abcdefg"
print(s[2])  #c
